package com.coovane.bytetrix.common.response;

import com.coovane.bytetrix.common.util.DateTimeUtils;
import com.coovane.bytetrix.common.util.UUIDUtils;

import java.io.Serializable;
import java.util.Date;
import java.util.Objects;

/**
 * <p>
 * 通用返回封装类
 * </p>
 *
 * @author: Hsu
 * @date: 2022/11/8 23:09
 * @copyright: companyName
 * @see
 * @since 1.8
 */
public class GenericResult<T> implements Serializable {

    private static final long serialVersionUID = -5207545231439124493L;
    private String requestId;
    private String code;
    private String message;
    private boolean success = true;
    private T data;
    private String timestamp;

    private GenericResult() {
    }

    private GenericResult(String requestId, String code, String message, T data) {
        this.requestId = requestId;
        this.code = code;
        this.message = message;
        this.data = data;
        this.timestamp = DateTimeUtils.date2String(new Date());
    }

    public static <T> GenericResult<T> success() {
        return success(null);
    }

    public static <T> GenericResult<T> success(T data) {
        return success("0", "请求成功", data);
    }

    public static <T> GenericResult<T> success(String message, T data) {
        return success("0", message, data);
    }

    public static <T> GenericResult<T> success(String code, String message, T data) {
        return new GenericResult<>(UUIDUtils.getLowerUUID("-", ""), code, message, data);
    }

    /**
     * 请求失败时，必须说明具体错误码和错误信息
     *
     * @param code    错误码
     * @param message 错误信息
     * @return
     */
    public static <T> GenericResult<T> fail(String code, String message) {
        return fail(code, message, null);
    }

    /**
     * 请求失败时，必须说明具体错误码和错误信息
     *
     * @param code    错误码
     * @param message 错误信息
     * @param <T>     响应对象
     * @return
     */
    public static <T> GenericResult<T> fail(String code, String message, T data) {
        GenericResult<T> result = new GenericResult<>(UUIDUtils.getLowerUUID("-", ""), code, message, data);
        result.setSuccess(false);
        return result;
    }

    public String getRequestId() {
        return requestId;
    }

    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        GenericResult<?> that = (GenericResult<?>) o;
        return success == that.success && Objects.equals(requestId, that.requestId) && Objects.equals(code, that.code) && Objects.equals(message, that.message) && Objects.equals(data, that.data) && Objects.equals(timestamp, that.timestamp);
    }

    @Override
    public int hashCode() {
        return Objects.hash(requestId, code, message, success, data, timestamp);
    }

    @Override
    public String toString() {
        return "GenericResult{" +
                "requestId='" + requestId + '\'' +
                ", code='" + code + '\'' +
                ", message='" + message + '\'' +
                ", success=" + success +
                ", data=" + data +
                ", timestamp='" + timestamp + '\'' +
                '}';
    }

}
